#include "DeductionView.h"

#include <boost/bind.hpp>
#include "../../../utils/LateEvents.hpp"
#include "../../helpers/remote/deduction/ShowDeductedCardsDialog.h"
#include "../../models/network/CardViewModel.h"

using namespace Views::Server;
using namespace Views::Helpers::Graphic::Deduction;
using namespace Utils;

DeductionView::DeductionView(Utils::GUI::Form* form, Domain::Network::GameServer* server, Players::Player* server_owner, Cards::CardsCollection cards):
Graphic::DeductionView(form), server(server), cards(cards), server_owner(server_owner)
{
}

void DeductionView::openPickSearchedCardsDialog(Players::Player* player, Cards::PlayersCards players_cards,
	Cards::WeaponsCards weapons_cards)
{
	asked_player = current_player = player;
	if (player == server_owner)
	{
		Graphic::DeductionView::openPickSearchedCardsDialog(player, players_cards, weapons_cards);
	}
	else
	{
		server->doOnReceiveData(
			Domain::Configuration::Network::DEDUCTION_SEARCHED_CARDS,
			boost::bind<void, DeductionView, Domain::Network::PlayerClient*, sf::Packet>(
				&DeductionView::onSearchedCardsPick, this, _1, _2
			)
		);
	}
}

void DeductionView::onSearchedCardsPick(Domain::Network::PlayerClient* player_client, sf::Packet packet)
{
	if (player_client->getPlayer() == current_player)
	{
		sf::Packet packet_copy = packet;
		Views::Models::Network::CardViewModel cvm(cards);
		Cards::PlayerCard* player_card = NULL;
		packet >> cvm;
		player_card = dynamic_cast<Cards::PlayerCard*>(cvm.card);
		Cards::WeaponCard* weapon_card = NULL;
		packet >> cvm;
		weapon_card = dynamic_cast<Cards::WeaponCard*>(cvm.card);
		server->sendToAll(Domain::Configuration::Network::DEDUCTION_SEARCHED_CARDS, packet_copy);

		searchedCardsPickEvent(player_card, weapon_card);
	}
}

void DeductionView::onSearchedCardsPick(Cards::PlayerCard* player_card, Cards::WeaponCard* weapon_card)
{
	sf::Packet packet;
	Views::Models::Network::CardViewModel cvm(player_card);
	packet << cvm;
	cvm.card = weapon_card;
	packet << cvm;
	server->sendToAll(Domain::Configuration::Network::DEDUCTION_SEARCHED_CARDS, packet);

	Graphic::DeductionView::onSearchedCardsPick(player_card, weapon_card);
}

void DeductionView::openPickCardDialog(Players::Player* player, Cards::CardSet& common_cards)
{
	current_player = player;
	if (player == server_owner)
	{
		Graphic::DeductionView::openPickCardDialog(player, common_cards);
	}
	else
	{
		server->doOnReceiveData(
			Domain::Configuration::Network::DEDUCTION_PICK_CARD,
			boost::bind<void, DeductionView, Domain::Network::PlayerClient*, sf::Packet>(
				&DeductionView::onDeductedCardPick, this, _1, _2
			)
		);
	}
}

void DeductionView::onDeductedCardPick(Domain::Network::PlayerClient* player_client, sf::Packet packet)
{
	if (player_client->getPlayer() == current_player)
	{
		sf::Packet packet_copy = packet;
		Views::Models::Network::CardViewModel cvm(cards);
		packet >> cvm;
		server->sendToAll(Domain::Configuration::Network::DEDUCTION_PICK_CARD, packet_copy);

		deductedCardPickEvent(cvm.card);
	}
}

void DeductionView::onDeductedCardPick(Cards::Card* card)
{
	sf::Packet packet;
	Views::Models::Network::CardViewModel cvm(card);
	packet << cvm;
	server->sendToAll(Domain::Configuration::Network::DEDUCTION_PICK_CARD, packet);

	Graphic::DeductionView::onDeductedCardPick(card);
}

void DeductionView::showDeductedCard(Cards::Card* card, Players::Player* current_player, Players::Player* card_owner)
{
	if (current_player == server_owner)
	{
		Graphic::DeductionView::showDeductedCard(card, current_player, card_owner);
	}
	else
	{
		CardInfo = new Helpers::Remote::Deduction::ShowDeductedCardsDialog(current_player, card_owner);
		Form->addChild(CardInfo);
		CardInfo->MoveCenter();
		Form->Draw(true);

		server->doOnReceiveData(Domain::Configuration::Network::DEDUCTION_CARD_SHOW,
			boost::bind(&DeductionView::onDeductedCardsDialogClose, this, _1, _2));
	}
}

void DeductionView::showNoCardsDeducted(Cards::CardSet& cards, Players::Player* player)
{
	if (current_player == server_owner)
	{
		Graphic::DeductionView::showNoCardsDeducted(cards, player);
	}
	else
	{
		CardInfo = new Helpers::Remote::Deduction::ShowNoCardsDeducted();
		Form->addChild(CardInfo);
		CardInfo->MoveCenter();
		Form->Draw(true);

		server->doOnReceiveData(Domain::Configuration::Network::DEDUCTION_CARD_SHOW,
			boost::bind(&DeductionView::onDeductedCardsDialogClose, this, _1, _2));
	}
}

void DeductionView::onDeductedCardsDialogClose()
{
	server->sendToAll(Domain::Configuration::Network::DEDUCTION_CARD_SHOW, sf::Packet());
	Graphic::DeductionView::onDeductedCardsDialogClose();
}

void DeductionView::onDeductedCardsDialogClose(Domain::Network::PlayerClient* player_client, sf::Packet packet)
{
	if (player_client->getPlayer() == asked_player)
	{
		delete CardInfo;
		server->sendToAll(Domain::Configuration::Network::DEDUCTION_CARD_SHOW, sf::Packet());
		deductedCardsShowEvent();
	}
}

